package com.binguo.wxapi.service;

import com.binguo.common.enums.*;
import com.binguo.common.exception.ServiceException;
import com.binguo.common.util.LoggerUtil;
import com.binguo.helper.FaceHelperV3;
import com.binguo.model.mapper.BinguoOrderMapper;
import com.binguo.model.mapper.CustomerExtendMapper;
import com.binguo.model.mapper.OrderItemMapper;
import com.binguo.model.mapper.PayCardMapper;
import com.binguo.model.model.*;
import com.binguo.model.repository.*;
import com.binguo.wxapi.form.external.RechargeForm;
import com.binguo.wxapi.util.BarcodeUtil;
import com.binguo.wxapi.vo.external.OrderForExternalVO;
import com.binguo.wxapi.vo.external.OrderItemForExternalVO;
import com.binguo.wxapi.vo.external.OrderResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class ABCBankService  {

    @Resource
    private PayCardMapper payCardMapper;


    @Autowired
    private CustomerRepository customerRepository;

    @Autowired
    private ShopRepository shopRepository;

    @Autowired
    private FaceRepository faceRepository;

    @Autowired
    private LogAbcBankRechargeRepository logAbcBankRechargeRepository;

    @Resource
    private CustomerExtendMapper customerExtendMapper;

    @Resource
    private BinguoOrderMapper binguoOrderMapper;

    @Resource
    private OrderItemMapper orderItemMapper;

    //天津农行
    public static int shopId = 116;


    public OrderResultVO orderList(String phone, Integer page){

        Integer customerId = getCustomerId(phone);

        Condition condition = new Condition(BinguoOrder.class);
        condition.or().andEqualTo("shopid", shopId)
                .andEqualTo("customerid", customerId)
        ;

        int count = binguoOrderMapper.selectCountByCondition(condition);

        if (page < 1) {
            page = 1;
        }

        int offset = (page - 1) * 20;

        condition.setOrderByClause(" id desc limit " + offset + ", 20");

        List<BinguoOrder> binguoOrderList = binguoOrderMapper.selectByCondition(condition);

        OrderResultVO orderResultVO = new OrderResultVO();
        orderResultVO.setTotalCount(count);

        if (binguoOrderList != null && binguoOrderList.size() > 0) {

            List<String> orderNoList = binguoOrderList.stream().map(BinguoOrder::getOrderno).collect(Collectors.toList());

            Condition orderItemCondition = new Condition(OrderItem.class);

            orderItemCondition.or().andIn("orderno", orderNoList);

            List<OrderItem> orderItemList = orderItemMapper.selectByCondition(orderItemCondition);

            Map<String, List<OrderItem>> orderNoOrderItemMap = new HashMap<>();
            if (orderItemList != null && orderItemList.size() > 0) {
                for (OrderItem orderItem : orderItemList) {
                    List<OrderItem> tempOrderItemList = orderNoOrderItemMap.get(orderItem.getOrderno());

                    if (tempOrderItemList == null) {
                        tempOrderItemList = new ArrayList<>();
                        orderNoOrderItemMap.put(orderItem.getOrderno(), tempOrderItemList);
                    }
                    tempOrderItemList.add(orderItem);
                }
            }

            List<OrderForExternalVO> resultList = new ArrayList<>();

            for (BinguoOrder binguoOrder : binguoOrderList) {
                OrderForExternalVO orderForExternalVO = new OrderForExternalVO();
                orderForExternalVO.setCustomerId(binguoOrder.getCustomerid());
                orderForExternalVO.setCustomerName(binguoOrder.getCustomername());
                orderForExternalVO.setCustomerPhone(binguoOrder.getCustomerphone());

                List<OrderItem> orderItemL = orderNoOrderItemMap.get(binguoOrder.getOrderno());

                if (orderItemL != null) {
                    orderForExternalVO.setItemCount(orderItemL.size());
                    List<OrderItemForExternalVO> tempList = new ArrayList<>();
                    for (OrderItem o : orderItemL) {
                        OrderItemForExternalVO orderItemForExternalVO = new OrderItemForExternalVO();
                        orderItemForExternalVO.setPrice(o.getPrice());
                        orderItemForExternalVO.setProductId(o.getProductid());
                        orderItemForExternalVO.setProductName(o.getProductname());
                        orderItemForExternalVO.setQuantity(o.getQuantity());
                        orderItemForExternalVO.setRealPrice(o.getRealprice());
                        tempList.add(orderItemForExternalVO);
                    }
                    orderForExternalVO.setOrderItems(tempList);
                }else {
                    orderForExternalVO.setItemCount(0);
                }


                orderForExternalVO.setPayStatus(binguoOrder.getPaystatus());
                orderForExternalVO.setPayTime(binguoOrder.getPaytime().getTime());
                orderForExternalVO.setPayType(binguoOrder.getSource());

                if (StringUtils.isEmpty(binguoOrder.getProductOrderUrl())) {
                    if (StringUtils.hasText(binguoOrder.getSerialnumber())) {
                        orderForExternalVO.setProductOrderUrl("http://m.binguoai.com/" + binguoOrder.getSerialnumber() + ".jpg");
                    }
                }else {
                    orderForExternalVO.setProductOrderUrl(binguoOrder.getProductOrderUrl());
                }
                orderForExternalVO.setRealFee(binguoOrder.getRealfee());
                orderForExternalVO.setRefundFee(binguoOrder.getRefundfee());
                orderForExternalVO.setRefundStatus(binguoOrder.getRefundstatus());
                orderForExternalVO.setTotalFee(binguoOrder.getTotalfee());
                orderForExternalVO.setOrderNo(binguoOrder.getOrderno());
                orderForExternalVO.setOrderType(binguoOrder.getOrdertype());

                resultList.add(orderForExternalVO);
            }

            orderResultVO.setOrderList(resultList);
            return orderResultVO;
        }

        return orderResultVO;

    }


    public void close(String phone){

        Shop shop = shopRepository.findById(shopId);

        if (shop.getStatus() == 0 || shop.getStatus() == 3) {
            LoggerUtil.console.info("shop info:{}", shop.getName());
        } else {
            throw new ServiceException("商户状态异常");
        }


        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("phone", phone);

        List<Customer> customerList = customerRepository.findByCondition(condition);

        Customer customer = null;
        if (customerList != null && customerList.size() > 0) {
            customer = customerList.get(0);
        }

        if (customer == null) {
            throw new ServiceException("用户不存在");
        }

        Condition payCardCondition = new Condition(PayCard.class);
        payCardCondition.or().andEqualTo("shopid", shopId)
                .andEqualTo("customerid", customer.getId())
                .andEqualTo("cardtype", CardType.BINGUO_CARD.getCode())

        ;

        List<PayCard> payCardList = payCardMapper.selectByCondition(payCardCondition);

        if (payCardList != null && payCardList.size() > 0) {
            PayCard payCard = payCardList.get(0);

            PayCard temp = new PayCard();
            temp.setDeleted(true);
            temp.setId(payCard.getId());

            payCardMapper.updateByPrimaryKeySelective(temp);
        }

        Condition faceCondition = new Condition(Face.class);
        faceCondition.or().andEqualTo("persionid", shop.getId() + "_" + customer.getId());
        List<Face> faceList = faceRepository.findByCondition(faceCondition);
        if (faceList != null && faceList.size() > 0) {
            FaceHelperV3.deletePerson(shop.getId() + "_" + customer.getId());
            faceRepository.deleteByCondition(faceCondition);
        }


        Condition customerExtendCondition = new Condition(CustomerExtend.class);
        customerExtendCondition.or().andEqualTo("customerId", customer.getId())
                .andEqualTo("shopId", shopId)
        ;
        List<CustomerExtend> customerExtendList =
                customerExtendMapper.selectByCondition(customerExtendCondition);

        if (customerExtendList != null && customerExtendList.size() > 0) {
            CustomerExtend customerExtend = customerExtendList.get(0);

            if (customerExtend.getIsAudit().intValue() == 1) {
                CustomerExtend temp = new CustomerExtend();
                temp.setIsAudit(0);
                temp.setId(customerExtend.getId());

                customerExtendMapper.updateByPrimaryKeySelective(temp);
            }
        }
    }


    public void removeAll(){

        Shop shop = shopRepository.findById(shopId);

        if (shop.getStatus() == 0 || shop.getStatus() == 3) {
            LoggerUtil.console.info("shop info:{}", shop.getName());
        } else {
            throw new ServiceException("商户状态异常");
        }


        Condition payCardCondition = new Condition(PayCard.class);
        payCardCondition.or().andEqualTo("shopid", shopId)
                .andEqualTo("cardtype", CardType.BINGUO_CARD.getCode())

        ;

        List<PayCard> payCardList = payCardMapper.selectByCondition(payCardCondition);

        if (payCardList != null && payCardList.size() > 0) {
            PayCard temp = new PayCard();
            temp.setDeleted(true);

            payCardMapper.updateByConditionSelective(temp, payCardCondition);
        }

        Condition faceCondition = new Condition(Face.class);
        faceCondition.or().andLike("persionid", shop.getId() + "_%");
        List<Face> faceList = faceRepository.findByCondition(faceCondition);
        if (faceList != null && faceList.size() > 0) {
            for (Face face : faceList) {
                FaceHelperV3.deletePerson(face.getPersionid());
            }
            faceRepository.deleteByCondition(faceCondition);
        }


        Condition customerExtendCondition = new Condition(CustomerExtend.class);
        customerExtendCondition.or()
                .andEqualTo("shopId", shopId)
        ;
        List<CustomerExtend> customerExtendList =
                customerExtendMapper.selectByCondition(customerExtendCondition);

        if (customerExtendList != null && customerExtendList.size() > 0) {
            for (CustomerExtend customerExtend : customerExtendList) {
                if (customerExtend.getIsAudit().intValue() == 1) {
                    CustomerExtend temp = new CustomerExtend();
                    temp.setId(customerExtend.getId());
                    temp.setIsAudit(0);

                    customerExtendMapper.updateByPrimaryKeySelective(temp);
                }
            }
        }
    }

    public void register(String phone, String faceUrl, String username){

        Shop shop = shopRepository.findById(shopId);

        if (shop.getStatus() == 0 || shop.getStatus() == 3) {
            LoggerUtil.console.info("shop info:{}", shop.getName());
        } else {
            throw new ServiceException("商户状态异常");
        }

        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("phone", phone);

        List<Customer> customerList = customerRepository.findByCondition(condition);

        Customer customer = null;
        String faceID = null;
        if (customerList != null && customerList.size() > 0) {
            customer = customerList.get(0);

            Condition customerExtendCondition = new Condition(CustomerExtend.class);
            customerExtendCondition.or().andEqualTo("customerId", customer.getId())
                    .andEqualTo("shopId", shop.getId())
            ;

            List<CustomerExtend> customerExtendList = customerExtendMapper.selectByCondition(customerExtendCondition);

            if (customerExtendList != null && customerExtendList.size() > 0) {
                CustomerExtend customerExtend = customerExtendList.get(0);
                if (customerExtend.getIsAudit() == 0) {
                    CustomerExtend temp = new CustomerExtend();
                    temp.setIsAudit(1);
                    temp.setId(customerExtend.getId());

                    customerExtendMapper.updateByPrimaryKeySelective(temp);
                }
            }

            Condition payCardCondition = new Condition(PayCard.class);
            payCardCondition.or()
                    .andEqualTo("customerid", customer.getId())
                    .andEqualTo("shopid", shopId)
                    .andEqualTo("cardtype", CardType.BINGUO_CARD.getCode())
            ;

            List<PayCard> payCardList = payCardMapper.selectByCondition(payCardCondition);

            boolean existed = false;
            if (payCardList != null && payCardList.size() > 0) {
                for (PayCard payCard : payCardList) {
                    if (payCard.getShopid().intValue() == shopId) {
                        existed = true;

                        if (payCard.getDeleted()) {
                            PayCard tempPayCard = new PayCard();
                            tempPayCard.setId(payCard.getId());
                            tempPayCard.setDeleted(false);

                            payCardMapper.updateByPrimaryKeySelective(tempPayCard);

                        }
                        break;
                    }else {
                        throw new ServiceException("用户已存在");
                    }
                }
            }

            int score = FaceHelperV3.detectFace(shopId, faceUrl);
            if (score < 70) {
                throw new ServiceException("人脸图片质量不合格");
            }

            if (existed) {
                //已经创建过
                Condition tempFaceExample = new Condition(Face.class);
                tempFaceExample.or().andEqualTo("customerId",customer.getId())
                    .andEqualTo("persionid", shopId + "_" + customer.getId())
                ;
                List<Face> tempFaceList = faceRepository.findByCondition(tempFaceExample);

                boolean faceAdded = false;
                if (tempFaceList != null && tempFaceList.size() > 0) {
                    for (Face face : tempFaceList) {
                        if (face.getFaceurl().equals(faceUrl)) {
                            faceAdded = true;
//                            throw new ServiceException("此图片已经添加");
                        }
                    }
                    if (!faceAdded) {
                        faceID = FaceHelperV3.addFace(shopId + "_" + customer.getId(), faceUrl);
                    }
                }else {
                    faceID = FaceHelperV3.addFace(shopId + "_" + customer.getId(), faceUrl);

                }

            }else{
                faceID = createPayCardAndFace(customer.getId(), faceUrl, shop.getName());
            }

        }else {
            customer = new Customer();
            customer.setName(username);
            customer.setCreated(new Date());
            customer.setUpdated(customer.getCreated());
            customer.setPhone(phone);
            customerRepository.save(customer);

            faceID = createPayCardAndFace(customer.getId(), faceUrl, shop.getName());
        }

        //此图片未创建
        if (faceID != null) {
            Face temp = new Face();
            temp.setFaceid(faceID);
            temp.setCustomerId(customer.getId());
            temp.setFaceurl(faceUrl);
            temp.setPersionid(shopId + "_" + customer.getId());
            faceRepository.save(temp);
        }

    }

    public PayCard getPayCard(Integer customerId){

        Condition payCardCondition = new Condition(PayCard.class);
        payCardCondition.or().andEqualTo("shopid", shopId)
                    .andEqualTo("customerid", customerId)
                    .andEqualTo("cardtype", CardType.BINGUO_CARD.getCode())
                    .andEqualTo("deleted", 0)

        ;

        List<PayCard> payCardList = payCardMapper.selectByCondition(payCardCondition);

        if (payCardList != null && payCardList.size() > 0) {
            PayCard payCard = payCardList.get(0);

            String payCode = BarcodeUtil.createPayCode("" + payCard.getId());

            PayCard temp = new PayCard();
            temp.setId(payCard.getId());

            temp.setPayCode(payCode);
            temp.setPayCodeTime(new Date());

            payCardMapper.updateByPrimaryKeySelective(temp);

            payCard.setPayCode(payCode);

            return payCard;
        }
        return null;
    }

    public void recharge(RechargeForm rechargeForm) {
        String phone = rechargeForm.getPhone();

        String amount = rechargeForm.getAmount();

        LogAbcBankRecharge logAbcBankRecharge = new LogAbcBankRecharge();
        logAbcBankRecharge.setAmount(rechargeForm.getAmount());
        logAbcBankRecharge.setCreateTime(new Date());
        logAbcBankRecharge.setOrderNo(rechargeForm.getOrderNo());
        logAbcBankRecharge.setUsername(rechargeForm.getUsername());
        logAbcBankRecharge.setPhone(rechargeForm.getPhone());
        logAbcBankRecharge.setRechargeTime(rechargeForm.getOrderTime());
        logAbcBankRechargeRepository.save(logAbcBankRecharge);

        if (StringUtils.hasText(amount) && Long.valueOf(amount) >= 0) {

            LoggerUtil.console.info("recharge, phone:{}, amount:{}", phone, amount);
        } else {
            throw new ServiceException("金额不正确");
        }


        Shop shop = shopRepository.findById(shopId);

        if (shop.getStatus() == 0 || shop.getStatus() == 3) {
            LoggerUtil.console.info("shop info:{}", shop.getName());
        } else {
            throw new ServiceException("商户状态异常");
        }

        Condition customerCondition = new Condition(Customer.class);
        customerCondition.or().andEqualTo("phone", phone);
        List<Customer> customerList = customerRepository.findByCondition(customerCondition);

        Integer customerId = null;
        Customer customer = null;
        if (customerList != null && customerList.size() > 0) {
            customer = customerList.get(0);

            customerId = customer.getId();
        }

        if (customerId == null) {
            throw new ServiceException("用户不存在");
        }

        Condition condition = new Condition(PayCard.class);

        condition.or().andEqualTo("customerid", customerId).andEqualTo("shopid", shopId)
                .andEqualTo("cardtype", CardType.BINGUO_CARD.getCode())
        ;

        addCustomerExtend(customerId);


        List<PayCard> payCardList = payCardMapper.selectByCondition(condition);

        PayCard payCard = null;
        if (payCardList != null && payCardList.size() > 0) {
            payCard = payCardList.get(0);

            PayCard temp = new PayCard();
            temp.setId(payCard.getId());
            temp.setAccountbalance(payCard.getAccountbalance() + Long.valueOf(amount));
            temp.setDeleted(false);

            payCardMapper.updateByPrimaryKeySelective(temp);

        }else {
            payCard = PayCard.builder()
                    .shopid(Integer.valueOf(shopId))
                    .customerid(customerId)
                    .cardno(null)
                    .cardtype(CardType.BINGUO_CARD.getCode().byteValue())
                    .deleted(false)
                    .name(shop.getName() + "卡")
                    .wxAccountbalance(0l)
                    .bzAccountbalance(0l)
                    .yktAccountbalance(0l)
                    .accountbalance(Long.valueOf(amount))
                    .ismaster(true)
                    .isnopasswordpay(true)
                    .build();

            payCardMapper.insertSelective(payCard);


            if (payCard.getId() != null) {
                PayCard tempPayCard = new PayCard();
                tempPayCard.setId(payCard.getId());
                tempPayCard.setCardno(String.valueOf(payCard.getId()));
                payCardMapper.updateByPrimaryKeySelective(tempPayCard);
            }

            Condition faceCondition = new Condition(Face.class);
            faceCondition.or().andEqualTo("customerId", customerId);
            List<Face> faceList = faceRepository.findByCondition(faceCondition);

            try {
                if (faceList != null && faceList.size() > 0) {
                    int i=0;
                    for (Face face : faceList) {
                        String personId = shopId + "_" + customerId;
                        String faceId = null;
                        if (i == 0) {
                            faceId = FaceHelperV3.createPerson(String.valueOf(shopId), personId, face.getFaceurl());
                        }else {
                            faceId = FaceHelperV3.addFace(personId, face.getFaceurl());
                        }
                        i++;

                        if (faceId == null) {
                            continue;
                        }
                        Face temp = new Face();
                        temp.setFaceid(faceId);
                        temp.setFaceurl(face.getFaceurl());
                        temp.setPersionid(personId);
                        temp.setCustomerId(customerId);
                        temp.setIsDeleted(0);
                        faceRepository.save(temp);
                    }
                }

            } catch (Exception e) {
                LoggerUtil.console.error(e.getMessage());

            }
        }



        String orderNo = UUID.randomUUID().toString().replace("-", "");
        BinguoOrder order = BinguoOrder.builder()
                .orderno(orderNo)
                .cardid(payCard.getId())
                .shopid(shopId)
                .openid(customer.getOpenid())
                .customerid(customerId)
                .customername(customer.getName())
                .customerphone(customer.getPhone())
                .source(PayType.OTHERPAY.getCode().byteValue())
                .totalfee(Long.valueOf(amount))
                .realfee(Long.valueOf(amount))
                .totalquantity(1)
                .ordertype(OrderType.CARD.getCode())
                .paystatus(PayStatus.SUCCESS.getCode().byteValue())
                .refundstatus(RefundStatus.UN_REFUND.getCode().byteValue())
                .build();
        binguoOrderMapper.insertSelective(order);
    }

    private String createPayCardAndFace(Integer customerId, String faceUrl, String shopName){
        PayCard payCard = PayCard.builder()
                .shopid(Integer.valueOf(shopId))
                .customerid(customerId)
                .cardno(null)
                .cardtype(CardType.BINGUO_CARD.getCode().byteValue())
                .deleted(false)
                .name(shopName + "卡")
                .wxAccountbalance(0l)
                .bzAccountbalance(0l)
                .yktAccountbalance(0l)
                .accountbalance(0l)
                .ismaster(true)
                .isnopasswordpay(true)
                .build();

        payCardMapper.insertSelective(payCard);

        PayCard tempPaycard = new PayCard();
        tempPaycard.setCardno(payCard.getId() + "");
        tempPaycard.setId(payCard.getId());

        payCardMapper.updateByPrimaryKeySelective(tempPaycard);

        addCustomerExtend(customerId);

        String faceID = FaceHelperV3.createPerson(String.valueOf(shopId),
                shopId + "_" + customerId, faceUrl);

        return faceID;
    }

    private void addCustomerExtend(Integer customerId) {
        Condition customerExtendCondition = new Condition(CustomerExtend.class);
        customerExtendCondition.or().andEqualTo("customerId", customerId)
            .andEqualTo("shopId", shopId)
        ;
        List<CustomerExtend> customerExtendList =
                customerExtendMapper.selectByCondition(customerExtendCondition);

        if (customerExtendList != null && customerExtendList.size() > 0) {
            CustomerExtend customerExtend = customerExtendList.get(0);

            if (customerExtend.getIsAudit().intValue() == 0) {
                CustomerExtend temp = new CustomerExtend();
                temp.setIsAudit(1);
                temp.setId(customerExtend.getId());

                customerExtendMapper.updateByPrimaryKeySelective(temp);
            }
        }else {
            CustomerExtend customerExtend = new CustomerExtend();
            customerExtend.setShopId(shopId);
            customerExtend.setCustomerId(customerId);
            customerExtend.setUserStatus(1);
            customerExtend.setIsAudit(1);
            customerExtendMapper.insertSelective(customerExtend);
        }
    }


    private Integer getCustomerId(String phone) {
        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("phone", phone);

        List<Customer> customerList = customerRepository.findByCondition(condition);

        Customer customer = null;
        if (customerList != null && customerList.size() > 0) {
            customer = customerList.get(0);
        }

        if (customer == null) {
            throw new ServiceException("用户不存在");
        }


        Condition payCardCondition = new Condition(PayCard.class);
        payCardCondition.or().andEqualTo("shopid", shopId)
                .andEqualTo("customerid", customer.getId())
                .andEqualTo("cardtype", CardType.BINGUO_CARD.getCode())

        ;

        List<PayCard> payCardList = payCardMapper.selectByCondition(payCardCondition);

        if (payCardList != null && payCardList.size() > 0) {
            return customer.getId();
        }

        throw new ServiceException("用户不存在");
    }
}
